
package ploy.compiler;

import java.util.*;

import org.objectweb.asm.*;
import org.objectweb.asm.util.*;
import org.objectweb.asm.commons.*;

import ploy.lang.*;

class Define extends AST {

    private Symbol name;
    private AST value;

    public Define( Symbol n, AST v ) {
	name = n;
	value = v;
    }

    public String toString( ) {
	return "(define " + name.toString( ) + " " + value.toString( ) + ")";
    }

    protected TreeSet<Symbol> calculateFreeVars( ) {
	return value.freeVars( );
    }

    public TreeSet<Lambda> allLambdas( ) {
	return value.allLambdas( );
    }

    public void locateVariables( VarLocationTable t ) {
	value.locateVariables( t );
    }

    public FrameSize generateBytecode( MethodVisitor mv ) {
	mv.visitTypeInsn(Opcodes.NEW, Symbol.jvmClass);
	mv.visitInsn(Opcodes.DUP);
	mv.visitLdcInsn( name.toString() );
	mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Symbol.jvmClass,
			   "<init>", "(Ljava/lang/String;)V");
	FrameSize valueFS = value.generateBytecode( mv );
	mv.visitMethodInsn(Opcodes.INVOKESTATIC, "ploy/lang/Globals",
			   "addGlobal", "(" +
			   Symbol.jvmType +
			   DynamicObject.jvmType + ")V");
	mv.visitTypeInsn(Opcodes.NEW, Nil.jvmClass);
	mv.visitInsn(Opcodes.DUP);
	mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Nil.jvmClass,
			   "<init>", "()V");
	return FrameSize.max( valueFS.addS( 1 ),
			      new FrameSize( 3, 0 ) );
    }
   
}
